前面有介紹過 attribute
可以引用的資料轉換器,用在 Active Model
可以在 initialize 時就直接對資料做轉型,相當方便,
然而這些轉換器,他們其實也可以直接單獨引用來當作資料轉換的 helper!
接著要介紹這些轉換器裡面個人認為最好用的一個,也就是今天的主角, ActiveModel::Type::Boolean
!
因為實在看過太多 code 裡面,對於要把各種輸入資料轉換成 true or false ,在不同的地方都有不同的判斷、各自的解讀,比如一定要是字串的 true
才算 true,或是輸入 0 是 false,1 是 true 等等,一個布林各自表述,如果專案一大起來,那各種轉換規則就是滿天飛舞,看得眼花撩亂.....。
不如,就乾脆來一套統一的判斷吧?
沒問題! ActiveModel::Type::Boolean
提供了一套很簡潔的解決方案,您要做的只有:
ActiveModel::Type::Boolean.new.cast(value)
就這樣,一行 code 解決!而且是整個專案統一規則,相當方便!
下面我們來試驗一下這東西:
ActiveModel::Type::Boolean.new.cast('0')
=> false
ActiveModel::Type::Boolean.new.cast('1')
=> true
ActiveModel::Type::Boolean.new.cast('false')
=> false
ActiveModel::Type::Boolean.new.cast('true')
=> true
ActiveModel::Type::Boolean.new.cast(:false)
=> false # symbol 也可以!
那他背後判斷的方式其實也很簡單,在 ActiveModel::Type::Boolean
裡面有設一個 constant 叫做 FALSE_VALUES
只要在這些值裡面,就一律當作是 false
,其他則一律全是 true
:
ActiveModel::Type::Boolean::FALSE_VALUES
=> #<Set: {false, 0, "0", :"0", "f", :f, "F", :F, "false", :false, "FALSE", :FALSE, "off", :off, "OFF", :OFF}>
# 使用 Set 加快 include 查詢效率
所以,雖然通常情況不太建議,但你其實可以根據你專案的需要,去針對這個 constant 加入你想要被判定為 false 的值。
當然,這種操作我一律建議做在 config/initializers
裡面。
# 比如我想要新增 "Y" 是 true,"N" 是 false 這樣一個轉換規則,
ActiveModel::Type::Boolean::FALSE_VALUES += ["N"]
# 用 .add 或者 << 都是不行的唷,因為他本身是 frozen object,所以只能用 += 這樣先 overwrite,之後再把他 freeze 一次
ActiveModel::Type::Boolean::FALSE_VALUES.freeze
這樣一來,我之後不管在專案哪個地方,都可以享用到同一套資料轉換規則:
ActiveModel::Type::Boolean.new.cast("Y")
=> true
ActiveModel::Type::Boolean.new.cast("N")
=> false
這樣一來是不是方便多了呢!